package kr.pe.johnkim.waiting.mobile.service;

import kr.pe.johnkim.waiting.mobile.dao.WaitingEventDao;
import kr.pe.johnkim.waiting.mobile.domain.WaitingEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;

/**
 * Waiting 이벤트 관련 Service 구현 클래스 이다.
 *
 * @author : John_Kim <cale9797@gmail.com>
 * @date : 13. 4. 24.
 */
@Service
public class WaitingEventServiceImpl implements WaitingEventService {

    // SLF4J Logging
    private Logger logger = LoggerFactory.getLogger(WaitingEventServiceImpl.class);

    @Autowired
    private WaitingEventDao waitingEventDao;

    /**
     * 이벤트를 등록 한다.
     *
     * @param waitingEvent
     */
    @Override
    public void registerEvent(WaitingEvent waitingEvent) {
        logger.info("registerEvent");
        this.waitingEventDao.registerEvent(waitingEvent);
    }

    /**
     * 이미지와 함께 이벤트를 등록 한다.
     *
     * @param waitingEvent
     * @param uploadImagePath
     * @param file
     */
    @Override
    public void registerEventWithImage(WaitingEvent waitingEvent, String uploadImagePath, String uploadThumbnailPath, MultipartFile file) {
        logger.info("registerEventWithImage");

        // 이지미를 등록 한다.
        // 이미지 파일명.
        String fileName = file.getOriginalFilename();

        logger.info("> file size : {}", file.getSize());
        logger.info("> file name : {}", file.getOriginalFilename());

        // 이미지를 업로드 한다.
        try {
            InputStream inputStream = file.getInputStream();
            OutputStream outputStream = new FileOutputStream(uploadImagePath + fileName);

            int bytesRead;

            byte[] buffer = new byte[8192];

            while((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

            outputStream.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 썸네일을 생성 한다.
        try {
            // 60x60 크기를 기준으로 설정 한다.
            int width = 60;
            int height = 60;

            File src = new File(uploadImagePath + fileName);

            BufferedImage bufferedImage = ImageIO.read(src);

            // Aspect Ratio 를 유지하기 위해서 크기를 조정 한다.
            if((float)width/bufferedImage.getWidth() > (float)height/bufferedImage.getHeight()) {
                width = (int)(bufferedImage.getWidth() * ((float)height/bufferedImage.getHeight()));
            } else {
                height = (int)(bufferedImage.getHeight() * ((float)width/bufferedImage.getWidth()));
            }

            BufferedImage thImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

            Graphics2D graphics2D = thImg.createGraphics();
            graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            graphics2D.drawImage(bufferedImage, 0, 0, width, height, null);
            graphics2D.dispose();

            File destinationFile = new File(uploadThumbnailPath + fileName);
            ImageIO.write(thImg, "png", destinationFile);
        } catch (Exception e) {
            e.printStackTrace();
        }

        this.waitingEventDao.registerEvent(waitingEvent);
    }

    /**
     * 이벤트를 수정 한다.
     *
     * @param waitingEvent
     */
    @Override
    public void updateEventInformation(WaitingEvent waitingEvent) {
        logger.info("updateEventInformation");
        this.waitingEventDao.updateEventInformation(waitingEvent);
    }

    /**
     * 이벤트 정보를 가져 온다.
     *
     * @param waitingEvent
     * @return
     */
    @Override
    public WaitingEvent selectEventInformation(WaitingEvent waitingEvent) {
        logger.info("selectEventInformation");
        return this.waitingEventDao.selectEventInformation(waitingEvent);
    }

    /**
     * 이벤트 목록을 가져 온다. 사용자의 smart phone 에 출력 된다.
     *
     * @param waitingEvent
     * @return
     */
    @Override
    public List<WaitingEvent> selectUserEventList(WaitingEvent waitingEvent) {
        logger.info("selectUserEventList");
        return this.waitingEventDao.selectUserEventList(waitingEvent);
    }

    /**
     * 이벤트 목록을 가져 온다. 가맹점의 iPad 에 출력 된다.
     *
     * @param waitingEvent
     * @return
     */
    @Override
    public List<WaitingEvent> selectMerchantEventList(WaitingEvent waitingEvent) {
        logger.info("selectMerchantEventList");
        return this.waitingEventDao.selectMerchantEventList(waitingEvent);
    }

    /**
     * 이벤트 활성화 여부를 업데이트 한다.
     *
     * @param waitingEvent
     */
    @Override
    public void updateEventActivateYn(WaitingEvent waitingEvent) {
        logger.info("updateEventActivateYn");
        this.waitingEventDao.updateEventActivateYn(waitingEvent);
    }
}
